/*
 * Copyright (c) 2006-2018, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2019-01-08     Ghazigq      first version
 */

#include <board.h>
#include <rthw.h>

#ifdef BSP_USING_OV2640
#include <ov2640.h>
#include <ov2640_cfg.h>

#define DBG_TAG             "drv.ov2640"
#define DBG_LVL             DBG_INFO
#include <rtdbg.h>

struct rt_i2c_bus_device  * ov2640_i2c_dev;

static uint8_t ov2640_read_reg(uint8_t reg)
{
    struct rt_i2c_msg msgs;
    uint8_t buff = 0;

    buff = reg;

    msgs.addr = CAMERA_IIC_BUS_ADDR;     /* 从机地址 */
    msgs.flags = RT_I2C_WR;     /* 写标志 */
    msgs.buf = &buff;             /* 读写数据缓冲区指针　*/
    msgs.len = 1;              /* 读写数据字节数 */

    /* 调用I2C设备接口传输数据 */
    rt_i2c_transfer(_camera.i2c_device, &msgs, 1);

    buff = 0;

    msgs.flags = RT_I2C_RD;     /* 读标志 */
    msgs.buf = &buff;             /* 读写数据缓冲区指针　*/
    msgs.len = 1;              /* 读写数据字节数 */
    rt_i2c_transfer(_camera.i2c_device, &msgs, 1);

    return buff;
}

static void ov2640_write_reg(uint8_t reg, uint8_t dat)
{
    struct rt_i2c_msg msgs;
    uint8_t buff[2] = {0};

    buff[0] = reg;
    buff[1] = dat;

    msgs.addr = CAMERA_IIC_BUS_ADDR;     /* 从机地址 */
    msgs.flags = RT_I2C_WR;     /* 读标志 */
    msgs.buf = buff;             /* 读写数据缓冲区指针　*/
    msgs.len = 2;              /* 读写数据字节数 */

    /* 调用I2C设备接口传输数据 */
    rt_i2c_transfer(_camera.i2c_device, &msgs, 1);
}

static void ov2640_set_outsize(uint16_t width,uint16_t height)
{
    uint16_t outh;
    uint16_t outw;
    uint8_t temp;
    if(width % 4)
    {
        LOG_E("camera width can't be divisible by 4");
        return;
    }
    if(height % 4)
    {
        LOG_E("camera height can't be divisible by 4");
        return;
    }
    outw = width / 4;
    outh = height / 4;
    camera_write_reg(0XFF,0X00);
    camera_write_reg(0XE0,0X04);
    camera_write_reg(0X5A,outw & 0XFF);        //设置OUTW的低八位
    camera_write_reg(0X5B,outh & 0XFF);        //设置OUTH的低八位
    temp = (outw >> 8) & 0X03;
    temp |= (outh >> 6) & 0X04;
    camera_write_reg(0X5C,temp);             //设置OUTH/OUTW的高位
    camera_write_reg(0XE0,0X00);
}

int ov2640_init(void)
{
    ov2640_i2c_dev = (struct rt_i2c_bus_device *)rt_device_find(OV2640_IIC_BUS_NAME);

    RT_ASSERT(ov2640_i2c_dev != RT_NULL);
}

#endif /* BSP_USING_OV2640 */
